package com.ffsky.litepack.dao;

import android.content.Context;

import com.ffsky.logger.L;

import net.sqlcipher.Cursor;
import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteOpenHelper;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;


/**
 *
 */
public class DataBaseManager extends SQLiteOpenHelper {


    public static  String TAG = "DataBase";

    private static String DB_PWD = "LITE_PACK";//数据库密码

    private static String DATABASE_NAME = "lite.db";

    private static int DATABASE_VERSION = 1;

    public static void setPassword(String password) {
        DB_PWD = password;
    }

    public static final void install(Context ctx, String dbName, int dbVersion) {
        if (instance == null) {
            DATABASE_NAME = dbName;
            DATABASE_VERSION = dbVersion;
            instance = new DataBaseManager(ctx);
            instance.addTable(KeyValueTable.getInstance());
        }
    }

    private final List<DatabaseTable> registeredTables;

    private static DataBaseManager instance;

    public static DataBaseManager getInstance() {
        return instance;
    }

    public static void unInstance() {
        if (instance != null) {
            instance.destroy();
            instance = null;
        }
    }

    public static final void reInit(Context ctx, String name) {
        if (instance != null) {
            instance.close();
        }
        DATABASE_NAME = name;
        instance = new DataBaseManager(ctx);
    }

    private DataBaseManager(Context ctx) {
        super(ctx, DATABASE_NAME, null,
                DATABASE_VERSION);
        registeredTables = new LinkedList<DatabaseTable>();
        SQLiteDatabase.loadLibs(ctx);
    }

    protected void destroy() {
        if (registeredTables != null) {
            registeredTables.clear();
        }
        close();
    }

    public synchronized SQLiteDatabase getWritableDatabase() {
        return super.getWritableDatabase(DB_PWD);
    }

    public synchronized SQLiteDatabase getReadableDatabase() {
        return super.getReadableDatabase(DB_PWD);
    }

    public Boolean tableIsExist(SQLiteDatabase db, String tableName) {
        boolean result = false;
        Cursor cursor = null;
        if (tableName == null) {
            return result;
        }
        String sql = "select count(*) from sqlite_master where type ='table' and name ='" + tableName.trim() + "'";
        cursor = db.rawQuery(sql, null);
        if (cursor.moveToNext()) {
            if (cursor.getInt(0) > 0) {
                result = true;
            }
        }
        return result;
    }

    public void checkTables() {
        List<DatabaseTable> _copy = new LinkedList<DatabaseTable>(registeredTables);
        SQLiteDatabase sqLiteDatabase = getReadableDatabase(DB_PWD);
        for (DatabaseTable table : _copy) {
            AbstractTable _absTable = (AbstractTable) table;
            boolean _hasTable = tableIsExist(sqLiteDatabase, _absTable.getTableName());
            if (!_hasTable) {
                _absTable.create(getWritableDatabase(DB_PWD));
            }
        }
    }

    public ArrayList<String> tablesInDB(SQLiteDatabase db) {
        ArrayList<String> list = new ArrayList<String>();
        String sql = "select name from sqlite_master where type='table'";
        Cursor cursor = db.rawQuery(sql, null);
        if (cursor.moveToFirst()) {
            do {
                String _name = cursor.getString(0);
                list.add(_name);
                L.d(TAG, "TableName-->" + _name);
            } while (cursor.moveToNext());
        }
        return list;
    }


    public void addTable(DatabaseTable table) {
        registeredTables.add(table);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        for (DatabaseTable table : registeredTables) {
            table.create(db);
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (newVersion > oldVersion) {
            for (DatabaseTable table : registeredTables) {
                table.migrate(db, oldVersion);
            }

            onCreate(db);
        }
    }

    public static void execSQL(SQLiteDatabase db, String sql) {
        db.execSQL(sql);
    }

    public static void dropTable(SQLiteDatabase db, String table) {
        execSQL(db, "DROP TABLE IF EXISTS " + table + ";");
    }

    public static void renameTable(SQLiteDatabase db, String table,
                                   String newTable) {
        execSQL(db, "ALTER TABLE " + table + " RENAME TO " + newTable + ";");
    }

    public void onClear() {
        for (DatabaseTable table : registeredTables)
            table.clear();
    }

    public void onLoad() {
        try {
//            getWritableDatabase(); // Force onCreate or onUpgrade
            tablesInDB(getWritableDatabase(DB_PWD));
            checkTables();
//            dropTable(getWritableDatabase(),"_Cookie");
//            dropTable(getWritableDatabase(),"_MeterialTableV3");
        } catch (Exception e) {
        }
    }

}
